#include "global_config.h"
#include "sys_hal.h"
#include <ArduinoJson.h>
// Import required libraries
#include "WiFi.h"
#include "ESPAsyncWebServer.h"
#include "LittleFS.h"

SysHal sysHal;


// Set LED GPIO
const int ledPin = 8;
// Stores LED state
String ledState;

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

int wifi_type = WIFI_AP;

// Replaces placeholder with LED state value
String processor(const String& var){
  Serial.println(var);
  if(var == "STATE"){
    if(digitalRead(ledPin)){
      ledState = "ON";
    }
    else{
      ledState = "OFF";
    }
    Serial.print(ledState);
    return ledState;
  }
  return String();
}

void SysHal::initWifimgr() {
    switch (wifi_type)
    {
        case WIFI_AP:
            // 参数:
            // local_ip – 本地IP 192.168.4.1
            // gateway – 网关IP 192.168.4.1
            // subnet – 子网掩码 255.255.255.0
            WiFi.softAP(WIFI_SSID, WIFI_PASSWORD);  //设置AP模式热点的名称和密码，密码可不填则发出的热点为无密码热点
            WiFi.softAPConfig(IPAddress(192,168,4,1), IPAddress(192,168,4,1), IPAddress(255,255,255,0));  //设置AP模式热点的IP地址，网关，子网掩码
            Serial.print("\nESP32建立的wifi名称为：");
            Serial.print(WIFI_SSID);  //串口输出ESP32建立的wifi的名称
            Serial.print("\nESP32建立wifi的IP地址为：");
            Serial.print(WiFi.softAPIP());  //串口输出热点的IP地址
            break;
        case WIFI_AP_STA:
            /* code */
            break;
        case WIFI_STA:
            Serial.print("\n连接wifi中...");
            WiFi.begin(WIFI_SSID, WIFI_PASSWORD);  //连接到指定的wifi名称和密码
            while (WiFi.status() != WL_CONNECTED) {
                delay(1000);
                Serial.println("Connecting to WiFi..");
            }
            // Print ESP32 Local IP Address
            Serial.print("IP Address: ");
            Serial.println(WiFi.localIP());
            break;
        default:
            break;
    }

}

int SysHal::getWifiType() {
    return wifi_type;
}

void SysHal::initWebServer() {
    Serial.println("\n初始化web配置");
    // Route for web configuration page
    server.on("/config", HTTP_GET, [](AsyncWebServerRequest *request){
        request->send(LittleFS, "/web/index.html", String(), false, processor);
    });

    // Initialize webserver URLs
    server.on("/api/wifi-info", HTTP_GET, [](AsyncWebServerRequest *request) {
        AsyncResponseStream *response = request->beginResponseStream("application/json");
        DynamicJsonDocument json(1024);
        json["status"] = "ok";
        json["ssid"] = WiFi.SSID();
        json["ip"] = WiFi.localIP().toString();
        serializeJson(json, *response);
        request->send(response);
    });

     server.on("/api/sys-info", HTTP_GET, [](AsyncWebServerRequest *request) {
        AsyncResponseStream *response = request->beginResponseStream("application/json");
        DynamicJsonDocument json(1024);
        uint64_t chipid=ESP.getEfuseMac();
        json["cores"] = ESP.getChipCores();
        json["chipRevision"] = ESP.getChipRevision();
        json["chipModel"] = ESP.getChipModel();
        json["heapSize"] = ESP.getHeapSize() / 1024;
        json["availableHeap"] = ESP.getFreeHeap() / 1024;
        json["totalPsramSize"] = ESP.getPsramSize() / 1024;
        json["availablePsram "] = ESP.getFreePsram() / 1024 ;
        json["cpuFreqMHz"] = ESP.getCpuFreqMHz();
        json["freeSketchSpace"] = ESP.getFreeSketchSpace() / 1024;

        serializeJson(json, *response);
        request->send(response);
    });

     // Initialize LittleFS
    if(!LittleFS.begin(true)){
        Serial.println("An Error has occurred while mounting LittleFS");
        return;
    }

   

    // Route for root / web page
    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
        request->send(LittleFS, "/web/index.html", String(), false, processor);
    });
    
    // Route to load style.css file
    server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
        request->send(LittleFS, "/web/style.css", "text/css");
    });


    // Start server
    server.begin();

}

// Print ESP32 WiFi status
void SysHal::wifiAPStatus() {
    Serial.print("主机名:");
  Serial.println(WiFi.softAPgetHostname());
  Serial.print("主机IP:");
  Serial.println(WiFi.softAPIP());
  Serial.print("主机IPV6:");
  Serial.println(WiFi.softAPIPv6());
  Serial.print("主机SSID:");
  Serial.println(WiFi.SSID());
  Serial.print("主机广播IP:");
  Serial.println(WiFi.softAPBroadcastIP());
  Serial.print("主机mac地址:");
  Serial.println(WiFi.softAPmacAddress());
  Serial.print("主机连接个数:");
  Serial.println(WiFi.softAPgetStationNum());
  Serial.print("主机网络ID:");
  Serial.println(WiFi.softAPNetworkID());
  Serial.print("主机状态:");
  Serial.println(WiFi.status());
}

void SysHal::init() {
    // Serial port for debugging purposes
    pinMode(ledPin, OUTPUT);
}

void SysHal::deinit() {
    delete this;
}